<template>

  <NuxtLayout name="manage-layout">
    <template #main>

      <div class="min-h-dvh flex justify-center">

        <div class="card bg-base-100 w-11/12 shadow-xl">
          <div class="card-body">
            <h4 class="card-title">用户列表</h4>
            <div class="stats shadow w-56">
              <div class="stat">
                <div class="stat-figure text-secondary cursor-pointer" @click="showFormModal(null)">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                       stroke="currentColor" class="size-6">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
                  </svg>
                </div>
                <div class="stat-title">用户数</div>
                <div class="stat-value">{{ tableData.total }}</div>
                <div class="stat-desc">Number of users</div>
              </div>
            </div>

            <div class="grid grid-cols-5 gap-4">
              <div class="form-control">
                <label class="label">
                  <span class="label-text text-sm font-semibold">角色</span>
                </label>
                <select class="select select-bordered input-md w-full max-w-xs" v-model="searchForm.role">
                  <option :value="''">全部</option>
                  <option v-for="item in roles" :value="item.value">{{ item.desc }}</option>
                </select>
              </div>

              <div class="form-control">
                <label class="label">
                  <span class="label-text text-sm font-semibold">账号</span>
                </label>
                <input type="text" v-model="searchForm.account" placeholder="请输入账号"
                       class="input input-md input-bordered"/>
              </div>

              <div class="form-control">
                <label class="label">
                  <span class="label-text text-sm font-semibold">姓名</span>
                </label>
                <input type="text" v-model="searchForm.name" placeholder="请输入姓名" class="input input-md input-bordered"/>
              </div>

              <div class="form-control">
                <label class="label">
                  <span class="label-text text-sm font-semibold">手机号</span>
                </label>
                <input type="text" v-model="searchForm.cellphoneNumber" placeholder="请输入手机号"
                       class="input input-md input-bordered"/>
              </div>

              <div class="form-control justify-self-center">
                <label class="label">
                  <span class="label-text text-sm font-semibold"></span>
                </label>
                <button class="btn btn-square btn-md btn-accent" @click="loadData()" title="查询">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                       stroke="currentColor" class="size-6">
                    <path stroke-linecap="round" stroke-linejoin="round"
                          d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"/>
                  </svg>
                </button>
              </div>

            </div>


            <div class="card bg-base-100 w-full shadow-xl">
              <div class="card-body">
                <div class="overflow-x-auto">
                  <table class="table">
                    <!-- head -->
                    <thead>
                    <tr>
                      <th></th>
                      <th>账号</th>
                      <th>姓名</th>
                      <th>手机号</th>
                      <th>角色</th>
                      <th>注册时间</th>
                      <th></th>
                    </tr>
                    </thead>
                    <tbody>
                    <!-- row 1 -->

                    <tr v-for="item in tableData.list" class="hover">
                      <td>
                        <div class="avatar" v-if="item.headImgKey">
                          <div class="w-12 rounded-xl">
                            <img :src="genFileUrl(item.headImgKey)"/>
                          </div>
                        </div>
                        <div class="avatar placeholder mask mask-squircle w-12" v-else>
                          <div class="bg-neutral text-neutral-content w-24 rounded-full opacity-80">
                            <span class="text-sm">{{ item.name.substring(0, 1) }}</span>
                          </div>
                        </div>
                      </td>
                      <td>{{ item.account }}</td>
                      <td>{{ item.name }}</td>
                      <td>{{ item.cellphoneNumber }}</td>
                      <td>{{ item.roleStr }}</td>
                      <td>{{ item.ct }}</td>
                      <td class="">
                        <button class="btn btn-xs mx-1 hover:bg-green-400" @click="showDetails(item.id)" title="查看">
                          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                               stroke="currentColor" class="size-6 hover:text-white">
                            <path stroke-linecap="round" stroke-linejoin="round"
                                  d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"/>
                            <path stroke-linecap="round" stroke-linejoin="round"
                                  d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>
                          </svg>
                        </button>
                        <button class="btn btn-xs mx-1 hover:bg-cyan-400" @click="showFormModal(item.id)" title="编辑">
                          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                               stroke="currentColor" class="size-6 hover:text-white">
                            <path stroke-linecap="round" stroke-linejoin="round"
                                  d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/>
                          </svg>
                        </button>
                        <!--                        超级管理员不允许删除-->
                        <button class="btn btn-xs mx-1 hover:bg-rose-400" @click="del(item.id)" v-if="item.role !== 0" title="删除">
                          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                               stroke="currentColor" class="size-6 hover:text-white">
                            <path stroke-linecap="round" stroke-linejoin="round"
                                  d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"/>
                          </svg>
                        </button>
                      </td>
                    </tr>

                    </tbody>
                  </table>
                </div>
              </div>
            </div>

            <div class="card-actions justify-center mt-6">
              <button @click="toPage(item)"
                      :class="'join-item btn-xs btn' + (item === searchForm.page ? ' btn-neutral ' : '')"
                      v-for="item in tableData.pagination">{{ item }}
              </button>
            </div>
          </div>
        </div>

        <dialog id="formModal" class="modal">
          <div class="modal-box">
            <form method="dialog">
              <button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2 focus:outline-none">✕</button>
            </form>
            <h3 class="text-lg font-bold">{{ editData === null ? '添加用户' : '编辑用户' }}</h3>
            <div class="w-full">
              <div class="flex justify-end">
                <img src="../../assets/images/login-welcome.jpeg" width="60">
              </div>
            </div>

            <div class="form-control">
              <label class="label">
                <span class="label-text"></span>
              </label>
              <input type="file" class="file-input file-input-bordered w-full max-w-xs hidden"
                     ref="fileInput" @change="handleFileChange"/>
              <div class="avatar flex justify-center tooltip cursor-pointer" data-tip="点击上传头像">
                <div class="mask mask-squircle w-24" v-if="headImgUrl">
                  <img @click="triggerFileUpload" :src="headImgUrl"/>
                </div>
                <div class="avatar placeholder mask mask-squircle w-24" v-else>
                  <div class="bg-neutral text-neutral-content w-24 rounded-full ring opacity-80"
                       @click="triggerFileUpload">
                    <span class="text-md">头像</span>
                  </div>
                </div>
              </div>
            </div>

<!--            超级管理员不展示角色这个选项-->
            <div class="form-control" v-if="form.role !== 0">
              <label class="label">
                <span class="label-text font-semibold">角色</span>
              </label>
              <select class="select select-bordered input-md" v-model="form.role" :disabled="editData !== null">
                <option v-for="item in editRoles" :value="item.value">{{ item.desc }}</option>
              </select>
            </div>
            <div class="form-control">
              <label class="label">
                <span class="label-text font-semibold">账号</span>
              </label>
              <input type="text" placeholder="请输入账号" v-model="form.account" class="input input-bordered"
                     :disabled="editData !== null"/>
            </div>
            <div class="form-control">
              <label class="label">
                <span class="label-text font-semibold">昵称</span>
              </label>
              <input type="text" placeholder="请输入昵称" v-model="form.name" class="input input-bordered"/>
            </div>
            <div class="form-control">
              <label class="label justify-start">
                <span class="label-text font-semibold">
                  手机号
                </span>
                <div class="lg:tooltip" data-tip="可找回密码">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                       stroke="currentColor" class="size-4">
                    <path stroke-linecap="round" stroke-linejoin="round"
                          d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"/>
                  </svg>
                </div>
              </label>
              <input type="text" placeholder="请输入手机号" v-model="form.cellphoneNumber" class="input input-bordered"/>
            </div>
            <div class="form-control">
              <label class="label">
                <span class="label-text font-semibold">密码</span>
              </label>
              <input type="password" placeholder="请输入密码" v-model="form.password" class="input input-bordered"/>
            </div>
            <div class="modal-action">
              <button class="btn btn-primary" @click="submitForm()">提交</button>
            </div>
          </div>
        </dialog>

        <dialog id="detailsModal" class="modal">
          <div class="modal-box">
            <form method="dialog">
              <button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
            </form>
            <h4 class="text-lg font-bold">个人信息</h4>

            <div class="card bg-base-100 w-full shadow-xl">
              <div class="card-body">
                <div class="grid grid-rows-4 grid-flow-col gap-4 mt-4">
                  <div class="row-span-2">
                    <div class="avatar flex justify-center">
                      <div class="mask mask-squircle w-24" v-if="details.headImgKey">
                        <img :src="genFileUrl(details.headImgKey)"/>
                      </div>
                      <div class="avatar placeholder mask mask-squircle w-24" v-else>
                        <div class="bg-neutral text-neutral-content w-24 rounded-full ring opacity-80">
                          <span class="text-md">头像</span>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">角色</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.roleStr }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">账号</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.account }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">姓名</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.name }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">手机号</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.cellphoneNumber }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">注册时间</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.ct }}</span>
                    </div>
                  </div>
                  <div>
                    <div class="form-control">
                      <label class="label">
                        <span class="label-text font-bold">最后更新时间</span>
                      </label>
                      <span class="">&nbsp;&nbsp;&nbsp;{{ details.ut }}</span>
                    </div>
                  </div>

                </div>
              </div>
            </div>

          </div>
        </dialog>

      </div>
    </template>
  </NuxtLayout>


</template>

<script setup>

import {genFileUrl, httpDel, httpGet, httpPost, postForm} from "../../utils/http/http-helper.js";
import {generatePaginationArray} from "../../utils/pagination/index.js";
import httpConfig from "../../utils/http/http-config.js";
import {notificationError, notificationSuccess} from "../../utils/notification/index.js";

definePageMeta({
  index: 'user',
})

const editData = ref(null)
const roles = ref([])
// 可编辑的角色 不允许创建超级管理员
const editRoles = ref([])
// 头像图片地址
const headImgUrl = ref('')
const fileInput = ref()

const searchForm = ref({
  page: 1,
  size: 10,
  role: '',
  account: '',
  cellphoneNumber: '',
  name: '',
})

const tableData = ref({
  list: [],
  total: 0,
  pagination: []
})

const details = ref({})


const form = ref({
  account: '',
  name: '',
  cellphoneNumber: '',
  password: '',
  role: 1,
  headImgKey: '',
})

function initForm(){
  form.value = {
    account: '',
    name: '',
    cellphoneNumber: '',
    password: '',
    role: 1,
    headImgKey: '',
  }
  headImgUrl.value = ''
}

if (process.client) {
  loadRoles()
  loadData()
}

/**
 * 加载角色列表
 */
function loadRoles() {
  httpGet('/api/enums/roles', searchForm.value).then(resp => {
    if (resp.success) {
      roles.value = resp.data
      for (let i = 0; i < roles.value.length; i++) {
        const tmp = roles.value[i]
        if (tmp.name !== 'SUPER_ADMIN') {
          editRoles.value.push(tmp)
        }
      }
    }
  })
}

/**
 * 加载用户数据
 */
function loadData() {
  httpGet('/api/users', searchForm.value).then(resp => {
    console.log(resp)
    if (!resp.success) {
      notificationError(resp.msg)
      return
    }
    const data = resp.data
    // 数据总数
    const total = data.totalElements
    tableData.value.list = data.content
    tableData.value.total = total
    // 当前页码
    const currentPage = searchForm.value.page
    const pageSize = searchForm.value.size
    const pagination = generatePaginationArray(total, pageSize, currentPage); // 生成分页数组
    tableData.value.pagination = pagination
  })
}

/**
 * 跳转到某页
 * @param selectedPage  页码
 */
function toPage(selectedPage) {
  searchForm.value.page = selectedPage
  loadData()
}


/**
 * 展示用户表单弹出框
 * @param id  主键ID null则为新增
 */
function showFormModal(id) {
  if (null !== id) {
    httpGet('/api/users/' + id).then(resp => {
      if (resp.success) {
        const data = resp.data
        editData.value = data
        form.value = data
        if(data.headImgKey !== ''){
          headImgUrl.value = genFileUrl(data.headImgKey)
        }
      }
    })
  } else {
    editData.value = null
    initForm()

  }
  formModal.showModal()

}

/**
 * 展示用户详情弹出框
 * @param id  用户ID
 */
function showDetails(id) {
  httpGet('/api/users/' + id).then(resp => {
    if (resp.success) {
      details.value = resp.data
      detailsModal.showModal()
    } else {
      notificationError(resp.msg)
    }
  })
}

/**
 * 删除某用户
 * @param id  用户ID
 */
function del(id) {
  httpDel('/api/users/' + id).then(resp => {
    if (resp.success) {
      notificationSuccess('删除成功')
      loadData()
    } else {
      notificationError(resp.msg)
    }
  })
}

/**
 * 关闭用户表单弹出框
 */
function closeFormModal(){
  formModal.close()
  initForm()
}

/**
 * 表单提交
 * 新增或更新用户
 */
function submitForm() {
  if (editData.value === null) {
    // 新增
    httpPost('/api/users', form.value).then(resp => {
      if (resp.success) {
        notificationSuccess('添加用户成功')
        closeFormModal()
        loadData()
      } else {
        notificationError(resp.msg)
      }
    })
  } else {
    // 更新
    httpPost('/api/users/' + editData.value.id, form.value).then(resp => {
      if (resp.success) {
        notificationSuccess('编辑用户成功')
        closeFormModal()
        loadData()
      } else {
        notificationError(resp.msg)
      }
    })
  }
}

/**
 * 弹出文件选择框
 */
function triggerFileUpload() {
  fileInput.value.click(); // 模拟用户点击文件输入
}

// 处理文件改变
function handleFileChange(event) {
  const file = event.target.files[0]; // 获取文件
  if (file) {
    // 执行文件上传操作
    uploadFile(file);
  }
}

// 上传文件的方法
function uploadFile(file) {
  // 这里可以添加上传文件的逻辑，比如使用 FormData 发送请求等
  console.log('Uploading file...', file);
  // 上传文件的代码...

  const formData = new FormData();
  // const file = rawFile.file;
  const filename = file.name
  if (!filename.endsWith(".png")
      && !filename.endsWith(".PNG")
      && !filename.endsWith(".jpg")
      && !filename.endsWith(".JPG")
      && !filename.endsWith(".jpeg")
      && !filename.endsWith(".JPEG")) {
    notificationError('请上传图片')
    return
  }
  formData.append('file', file);
  postForm('/api/files', formData).then(resp => {
    if (resp.success) {
      const data = resp.data
      form.value.headImgKey = data.compressKey
      headImgUrl.value = data.compressLocation

      console.log('上传文件...')
      console.log(data)
      console.log('上传文件...')

      notificationSuccess('上传头像成功')
    }
  }).catch(err => {
    console.log('err -> ' + err)
    notificationError(err)
  })
}

</script>

<style scoped>

</style>